package com.hskn.hss.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.hskn.hss.module.grid.entity.Grid;
import com.hskn.hss.module.gridSnapshot.entity.GridSnapshot;
import lombok.extern.slf4j.Slf4j;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;

import java.math.BigDecimal;

@Slf4j
public class DistanceUtils {

    /**
     * 判断坐标是不是在网格内
     * 通用网格
     *
     * @param lon  点的经度
     * @param lat  点的纬度
     * @param grid 网格
     * @return boolean
     */
    public static boolean insideGrid(Double lon, Double lat, Grid grid) {
        if (grid.getType() == null) {
            return false;
        }
        if (grid.getType() == 1 && grid.getAreaType() == null) {
            return false;
        }
        if (grid.getType() == 2 || grid.getType() == 3) {
//            log.info("==判断坐标是否网格内(insideGrid)-1,gridId:{}", grid.getGridId());
            // 路段
            return insideLine(lon, lat, grid.getLnglat());
        }
        Boolean inside = false;
        if (grid.getType() == 1) {
            if (grid.getAreaType() == 3) { // 圆形区域
                inside = DistanceUtils.insideCircle(lon,
                        lat, Double.valueOf(grid.getLng()),
                        Double.valueOf(grid.getLat()), grid.getRadius());
            } else if (grid.getAreaType() == 4) { // 矩形
                inside = DistanceUtils.insideRect(lon, lat, grid.getLnglat());
            } else if (grid.getAreaType() == 5) {//多边形区域
                inside = DistanceUtils.insidePolygon(lon, lat, grid.getLnglat());

            }
        } else if (grid.getType() == 2) { // 线路
            if (StringUtils.isNotEmpty(grid.getSectionIds())) {
                String[] sectionIds = grid.getSectionIds().split(",");
                for (String sectionId : sectionIds) {
                    if (sectionId.equals(grid.getGridId())) {
                        log.info("==判断坐标是否网格内(insideGrid)-2,gridId:{}", grid.getGridId());
                        inside = DistanceUtils.insideLine(lon, lat, grid.getLnglat());
                        if (inside) {
                            break;
                        }
                    }
                }
            }
        } else if (grid.getType() == 3) { // 路段
            log.info("==判断坐标是否网格内(insideGrid)-3,gridId:{}", grid.getGridId());
            inside = DistanceUtils.insideLine(lon, lat, grid.getLnglat());
        }
        return inside;
    }

    /**
     * 判断坐标是不是在网格内
     * 通用网格
     *
     * @param lon  点的经度
     * @param lat  点的纬度
     * @param grid 网格
     * @return boolean
     */
    public static boolean insideGrid(Double lon, Double lat, GridSnapshot grid) {
        if (grid.getType() == null) {
            return false;
        }
        if (grid.getType() == 1 && grid.getAreaType() == null) {
            return false;
        }
        if (grid.getType() == 2 || grid.getType() == 3) {
//            log.info("==判断坐标是否网格内(insideGrid)-1,gridId:{}", grid.getGridId());
            // 路段
            return insideLine(lon, lat, grid.getLnglat());
        }
        Boolean inside = false;
        if (grid.getType() == 1) {
            if (grid.getAreaType() == 3) { // 圆形区域
                inside = DistanceUtils.insideCircle(lon,
                        lat, Double.valueOf(grid.getLng()),
                        Double.valueOf(grid.getLat()), grid.getRadius());
            } else if (grid.getAreaType() == 4) { // 矩形
                inside = DistanceUtils.insideRect(lon, lat, grid.getLnglat());
            } else if (grid.getAreaType() == 5) {//多边形区域
                inside = DistanceUtils.insidePolygon(lon, lat, grid.getLnglat());

            }
        } else if (grid.getType() == 2) { // 线路
            if (StringUtils.isNotEmpty(grid.getSectionIds())) {
                String[] sectionIds = grid.getSectionIds().split(",");
                for (String sectionId : sectionIds) {
                    if (sectionId.equals(grid.getGridId())) {
                        log.info("==判断坐标是否网格内(insideGrid)-2,gridId:{}", grid.getGridId());
                        inside = DistanceUtils.insideLine(lon, lat, grid.getLnglat());
                        if (inside) {
                            break;
                        }
                    }
                }
            }
        } else if (grid.getType() == 3) { // 路段
            log.info("==判断坐标是否网格内(insideGrid)-3,gridId:{}", grid.getGridId());
            inside = DistanceUtils.insideLine(lon, lat, grid.getLnglat());
        }
        return inside;
    }

    /**
     * 判断坐标是不是在网格内
     * 通用网格
     *
     * @param lon  点的经度
     * @param lat  点的纬度
     * @param gridSnapshot 网格
     * @return boolean
     */
    public static boolean insideCopyGrid(Double lon, Double lat, GridSnapshot gridSnapshot) {
        if (gridSnapshot.getType() == null) {
            return false;
        }
        if (gridSnapshot.getType() == 1 && gridSnapshot.getAreaType() == null) {
            return false;
        }
        if (gridSnapshot.getType() == 2 || gridSnapshot.getType() == 3) {
//            log.info("==判断坐标是否网格内(insideGrid)-1,gridId:{}", grid.getGridId());
            // 路段
            return insideLine(lon, lat, gridSnapshot.getLnglat());
        }
        Boolean inside = false;
        if (gridSnapshot.getType() == 1) {
            if (gridSnapshot.getAreaType() == 3) { // 圆形区域
                inside = DistanceUtils.insideCircle(lon,
                        lat, Double.valueOf(gridSnapshot.getLng()),
                        Double.valueOf(gridSnapshot.getLat()), gridSnapshot.getRadius());
            } else if (gridSnapshot.getAreaType() == 4) { // 矩形
                inside = DistanceUtils.insideRect(lon, lat, gridSnapshot.getLnglat());
            } else if (gridSnapshot.getAreaType() == 5) {//多边形区域
                inside = DistanceUtils.insidePolygon(lon, lat, gridSnapshot.getLnglat());

            }
        } else if (gridSnapshot.getType() == 2) { // 线路
            if (StringUtils.isNotEmpty(gridSnapshot.getSectionIds())) {
                String[] sectionIds = gridSnapshot.getSectionIds().split(",");
                for (String sectionId : sectionIds) {
                    if (sectionId.equals(gridSnapshot.getGridId())) {
                        log.info("==判断坐标是否网格内(insideGrid)-2,gridId:{}", gridSnapshot.getGridId());
                        inside = DistanceUtils.insideLine(lon, lat, gridSnapshot.getLnglat());
                        if (inside) {
                            break;
                        }
                    }
                }
            }
        } else if (gridSnapshot.getType() == 3) { // 路段
            log.info("==判断坐标是否网格内(insideGrid)-3,gridId:{}", gridSnapshot.getGridId());
            inside = DistanceUtils.insideLine(lon, lat, gridSnapshot.getLnglat());
        }
        return inside;
    }

    /**
     * 判断坐标是不是在网格内
     * 路段
     *
     * @param lon    点的经度
     * @param lat    点的纬度
     * @param lnglat 网格坐标点集合
     * @return boolean
     */
    public static boolean insideLine(Double lon, Double lat, String lnglat, Double rangeMeter) {
        boolean inside = false;
        if (StringUtils.isNotEmpty(lnglat)) {
            JSONArray array = JSONArray.parseArray(lnglat);
            if (array.size() > 0) {
                String area = "";
                for (int j = 0; j < array.size(); j++) {
                    JSONObject json = JSON.parseObject(array.get(j).toString());
                    area += j > 0 ? ";" : "";
                    area += json.getString("lng") + "," + json.getString("lat");
                }
                double distance = DistanceUtils.getDistance(lon, lat, area);
                inside = distance < rangeMeter;
            }
        }
        return inside;
    }


    /**
     * 判断坐标是不是在网格内
     * 路段
     *
     * @param lon    点的经度
     * @param lat    点的纬度
     * @param lnglat 网格坐标点集合
     * @return boolean
     */
    public static boolean insideLine(Double lon, Double lat, String lnglat) {
        return insideLine(lon, lat, lnglat, 20d);
    }

    /**
     * 判断坐标是不是在网格内
     * 多边形
     *
     * @param lon    点的经度
     * @param lat    点的纬度
     * @param lnglat 网格坐标点集合
     * @return boolean
     */
    public static boolean insidePolygon(Double lon, Double lat, String lnglat) {
        boolean inside = false;
        if (StringUtils.isNotEmpty(lnglat)) {
            JSONArray array = JSONArray.parseArray(lnglat);
            if (array.size() > 0) {
                String area = "";
                for (int j = 0; j < array.size(); j++) {
                    JSONObject json = JSON.parseObject(array.get(j).toString());
                    area += j > 0 ? ";" : "";
                    area += json.getString("lng") + "," + json.getString("lat");
                }
                inside = DistanceUtils.isPtInPoly(lon, lat, area);
            }
        }
        return inside;
    }

    /**
     * 矩形
     *
     * @param lon
     * @param lat
     * @param lnglat
     * @return
     */
    public static boolean insideRect(Double lon, Double lat, String lnglat) {
        boolean inside = false;
        if (StringUtils.isNotEmpty(lnglat)) {
            JSONObject json = JSONObject.parseObject(lnglat);
            String area = "";
            String lng1 = JSONObject.parseObject(json.getString("Lq")).getString("lng");
            String lat1 = JSONObject.parseObject(json.getString("Lq")).getString("lat");
            String lng2 = JSONObject.parseObject(json.getString("kq")).getString("lng");
            String lat2 = JSONObject.parseObject(json.getString("kq")).getString("lat");

            area += lng1 + "," + lat1;
            area += ";";
            area += lng1 + "," + lat2;
            area += ";";
            area += lng2 + "," + lat2;
            area += ";";
            area += lng2 + "," + lat1;
            inside = DistanceUtils.isPtInPoly(lon, lat, area);
        }
        return inside;
    }


    /**
     * 判断坐标是不是在网格内
     * 圆
     *
     * @param lon    点的经度
     * @param lat    点的纬度
     * @param radius 圆的半径
     * @return boolean
     */
    public static boolean insideCircle(Double lon, Double lat, Double radiusLon, Double radiusLat, Double radius) {
        boolean inside = false;
        if (StringUtils.isNotEmpty(lat) && StringUtils.isNotEmpty(lon) && StringUtils.isNotEmpty(radius)) {
            Long distance = DistanceUtils.measureDistance(radiusLon, radiusLat, lon, lat);
            if (StringUtils.isNotEmpty(distance)) {
                inside = distance < radius;
            }
        }
        return inside;
    }

    /**
     * 判断点是否在范围内
     *
     * @param ALon
     * @param ALat
     * @param area
     * @return
     */
    public static boolean isPtInPoly(double ALon, double ALat, String area) {
        String[] location = area.trim().split(";");
        Point[] ps = new Point[location.length];
        for (int i = 0; i < location.length; i++) {
            Point aPoints = new Point();
            String[] alocation = location[i].split(",");
            aPoints.setX(new BigDecimal(alocation[0]).doubleValue());
            aPoints.setY(new BigDecimal(alocation[1]).doubleValue());
            ps[i] = aPoints;
        }

        int iSum, iCount, iIndex;
        double dLon1 = 0, dLon2 = 0, dLat1 = 0, dLat2 = 0, dLon;
        if (ps.length < 3) {
            return false;
        }
        iSum = 0;
        iCount = ps.length;
        for (iIndex = 0; iIndex < iCount; iIndex++) {
            if (iIndex == iCount - 1) {
                dLon1 = ps[iIndex].getX();
                dLat1 = ps[iIndex].getY();
                dLon2 = ps[0].getX();
                dLat2 = ps[0].getY();
            } else {
                dLon1 = ps[iIndex].getX();
                dLat1 = ps[iIndex].getY();
                dLon2 = ps[iIndex + 1].getX();
                dLat2 = ps[iIndex + 1].getY();
            }
            // 以下语句判断A点是否在边的两端点的水平平行线之间，在则可能有交点，开始判断交点是否在左射线上
            if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1))) {
                if (Math.abs(dLat1 - dLat2) > 0) {
                    //得到 A点向左射线与边的交点的x坐标：
                    dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat)) / (dLat1 - dLat2);
                    // 如果交点在A点左侧（说明是做射线与 边的交点），则射线与边的全部交点数加一：
                    if (dLon < ALon) {
                        iSum++;
                    }
                }
            }
        }
        if ((iSum % 2) != 0) {
            return true;
        }
        return false;
    }

    /**
     * 判断点距离最近范围边距离
     *
     * @param ALon
     * @param ALat
     * @param area
     * @return
     */
    public static double getDistance(double ALon, double ALat, String area) {
//        Boolean isPtInPolyIn = isPtInPoly(ALon, ALat, area);
//        if (isPtInPolyIn) {
//            return 0.0;
//        } else {
        String[] location = area.trim().split(";");
        Point[] ps = new Point[location.length];
        //注意 最后一个点会和第一个点相同,所以不再进行比较 这里用length-1
        for (int i = 0; i < location.length; i++) {
            Point aPoints = new Point();
            String[] alocation = location[i].split(",");
            aPoints.setX(new BigDecimal(alocation[0]).doubleValue());
            aPoints.setY(new BigDecimal(alocation[1]).doubleValue());
            ps[i] = aPoints;
//            log.info("围栏第" + (i + 1) + "个点的坐标为{经度X=" + ps[i].getX() + ",纬度Y=" + ps[i].getY());
        }

        Point localPoint = new Point(ALon, ALat);
//        log.info("车的当前坐标为 经度X=" + localPoint.getX() + ",纬度Y=" + localPoint.getY());
        /*
         * . sqrt((x-x)^2 +(y-y)^2)
         * 计算围栏哪个点 到 车车位置最短
         */
        Point minPoint;
        int index = -1;
        double min = Double.MAX_VALUE;
        double x2 = ALon;
        double y2 = ALat;
        //找到距离最近的点

        for (int i = 0; i < ps.length; i++) {
            Double x = ps[i].getX();
            Double y = ps[i].getY();
            double sqrt = get2PointDis(localPoint, ps[i]);
            if (sqrt <= min) {
                min = sqrt;
                index = i;
            }
//            log.info("车坐标正在与第" + (i + 1) + "个点进行比较距离,距离为:" + sqrt);
        }
//        log.info("我们得到最短的距离为:" + min);
        //获取距离最近的点
        if (index != -1) {
            minPoint = ps[index];
//            log.info("该点为 第" + (index + 1) + "个点,他的经度X=" + minPoint.getX() + ",纬度Y=" + minPoint.getY());
            //找到连接该点的 前后两个点
            Point beforePoint;
            Point afterPoint;
            if (index == ps.length - 1) {
                afterPoint = ps[0];
            } else {
                afterPoint = ps[index + 1];
            }
            if (index == 0) {
                beforePoint = ps[ps.length - 1];
            } else {
                beforePoint = ps[index - 1];
            }
//            log.info("我们已经找到最近点相连的前一个点,第" + (index) + "个他的坐标经度X=" + beforePoint.getX() + ",纬度Y=" + beforePoint.getY());
//            log.info("我们已经找到最近点相连的后一个点,第" + (index + 2) + "个他的坐标经度X=" + afterPoint.getX() + ",纬度Y=" + afterPoint.getY());
            /**
             *         计算 车点 到  距离最短点和其前后两点组成的线段 的距离哪个最短
             */
            // 车点1   最近点2  与最近点相连的前一点3
            boolean acuteAngle1 = false;
            double h1 = 0;
            if (index != 0) {
                double a1;// 1 -2 的边长
                double b1;// 2-3 的边长
                double c1;// 3-1 的边长
                // 海伦公式 得到三点围城三角形的面积
                a1 = get2PointDis(localPoint, minPoint);
                b1 = get2PointDis(minPoint, beforePoint);
                c1 = get2PointDis(beforePoint, localPoint);
//                log.info("通过计算,我们得到第一组三角形他们各边的边长是 { a=" + a1 + "b=" + b1 + "c=" + c1 + "}");
                //****重点  判断三角形是否为锐角三角形
                acuteAngle1 = isAcuteAngle(a1, b1, c1);
                h1 = a1;//距离 如果是锐角三角形 则高为最短距离,如果是钝角三角形,则最短距离是车到最近点
                if (acuteAngle1) {
                    double p1 = (a1 + b1 + c1) / 2;
//                    log.info("我们得到他的边长为:" + (a1 + b1 + c1) + ",他的海伦公式中p=" + p1);
                    double S1 = Math.sqrt(p1 * (p1 - a1) * (p1 - b1) * (p1 - c1));
//                    log.info("我们通过海伦公式得到他的面积为:" + S1);
                    //求高 也就是距离
                    h1 = (2 * S1) / b1;
//                    log.info("该三角形是锐角三角形 以 除车点其余两点 组成的边长为底 高为:" + h1);
                } else {
//                    log.info("该三角形是钝角三角形 以 除车点其余两点 组成的边长为底 高为:" + h1);
                }
            }
            // 车点1   最近点2   与最近点相连的后一点3
            boolean acuteAngel2 = false;
            double h2 = 0;
            if (index != ps.length - 1) {
                double a2;// 1 -2 的边长
                double b2;// 2-3 的边长
                double c2;// 3-1 的边长

                // 海伦公式 得到三点围城三角形的面积
                a2 = get2PointDis(localPoint, minPoint);
                b2 = get2PointDis(minPoint, afterPoint);
                c2 = get2PointDis(afterPoint, localPoint);
                h2 = a2;
                acuteAngel2 = isAcuteAngle(a2, b2, c2);
                if (acuteAngel2) {
//                    log.info("通过计算,我们得到第二组三角形他们各边的边长是 { a=" + a2 + "b=" + b2 + "c=" + c2 + "}");
                    double p2 = (a2 + b2 + c2) / 2;
//                    log.info("我们得到他的边长为:" + (a2 + b2 + c2) + ",他的海伦公式中p=" + p2);
                    double S2 = Math.sqrt(p2 * (p2 - a2) * (p2 - b2) * (p2 - c2));
//                    log.info("我们通过海伦公式得到他的面积为:" + S2);
                    //求高 也就是距离
                    h2 = (2 * S2) / b2;
//                    log.info("该三角形是锐角三角形 以 除车点其余两点 组成的边长为底 高为:" + h2);
                } else {
//                    log.info("该三角形是钝角三角形 以 除车点其余两点 组成的边长为底 高为:" + h2);
                }
            }
            if (index == 0) {
                return h2;
            } else if (index == ps.length - 1) {
                return h1;
            } else {
                if ((acuteAngle1 && acuteAngel2) || (!acuteAngle1 && !acuteAngel2)) {
//                    log.info("两个三角形同为锐角,或者同为钝角");
                    return h1 < h2 ? h1 : h2;
                } else if (acuteAngle1 && !acuteAngel2) {
//                    log.info("一号三角形为 锐角,二号三角形为钝角,取锐角");
                    return h1;
                } else if (!acuteAngle1 && acuteAngel2) {
//                    log.info("一号三角形为钝角,二号三角形为锐角,取锐角");
                    return h2;
                }
            }
        }
        return 0;
//        }
    }

    private static double rad(double d) {
        return d * Math.PI / 180.0;
    }

    private static final Double EARTH_RADIUS = 6378.137;

    /**
     * 计算距离
     */
    public static double get2PointDis(Point p1, Point p2) {
        double radLat1 = rad(p1.getY());
        double radLat2 = rad(p2.getY());
        double a = radLat1 - radLat2;
        double b = rad(p1.getX()) - rad(p2.getX());
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLat1) * Math.cos(radLat2)
                * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        s = Math.round(s * 10000d) / 10000d;
        s = s * 1000;
        return s;
    }

    /**
     * 判断是否锐角三角形.
     */
    private static boolean isAcuteAngle(double a, double b, double c) {
        return ((b * b + a * a - c * c) >= 0) && ((b * b + c * c - a * a) >= 0);
    }

    /**
     * 计算地球两坐标点之间的距离
     *
     * @param lng1 点1经度
     * @param lat1 点1纬度
     * @param lng2 点2经度
     * @param lat2 点2纬度
     * @return 距离，单位米
     */
    public static Long measureDistance(Double lng1, Double lat1, Double lng2, Double lat2) {
        if (StringUtils.isEmpty(lng1) || StringUtils.isEmpty(lat1) || StringUtils.isEmpty(lng2) || StringUtils.isEmpty(lat2)) {
            return null;
        }
        double EARTH_RADIUS = 6378137;
        long distance = 0;
        double radLatitude1 = lat1 * Math.PI / 180.0;
        double radLatitude2 = lat2 * Math.PI / 180.0;
        double a = Math.abs(radLatitude1 - radLatitude2);
        double b = Math.abs(lng1 * Math.PI / 180.0 - lng2 * Math.PI / 180.0);
        double s = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(a / 2), 2)
                + Math.cos(radLatitude1) * Math.cos(radLatitude2) * Math.pow(Math.sin(b / 2), 2)));
        s = s * EARTH_RADIUS;
        distance = Math.round(s * 10000) / 10000;
        return distance;
    }

    /**
     * 余弦定理
     * @param a
     * @param b
     * @param c
     * @return
     */
    public static double getAngleByThreeSides(double a, double b, double c){
        if(a == 0 || c == 0 || b == 0){
            return 90;
        }else{
            return arccos((a*a + c*c - b*b)/(2*a*c));
        }
    }
    /**
     * 计算三点之间的角度
     */
    public static double getAngleByThreePoints(double lng1, double lat1, double lng2, double lat2, double lng3, double lat3){
        Double a = (double)measureDistance(lng1,lat1,lng2,lat2);
        Double b = (double)measureDistance(lng1,lat1,lng3,lat3);
        Double c = (double)measureDistance(lng2,lat2,lng3,lat3);
        Double a2 = sqrt((lng1 - lng2) * (lng1 - lng2) + (lat1 - lat2) * (lat1 - lat2));
        Double b2 = sqrt((lng1 - lng3) * (lng1 - lng3) + (lat1 - lat3) * (lat1 - lat3));
        Double c2 = sqrt((lng3 - lng2) * (lng3 - lng2) + (lat3 - lat2) * (lat3 - lat2));
        Double angle = getAngleByThreeSides(a, b, c);
        Double angle2 = getAngleByThreeSides(a2, b2, c2);
        return angle;
    }
    private static double sqrt (double c) {
        if (c < 0) return Double.NaN;
        double err = 1e-15;
        double t = c;
        while( Math.abs(t - c/t) > err * t)
            t = (c/t + t) /2.0;
        return t;
    }
    /**
     * 余弦反算函数，精度到0.03秒
     * @param a double 余弦值
     * @return double   角度(360)
     */
    public static double arccos(double a)
    {
        double b = 90.0, c0 = 0.0, c1 = 180.0;
        if (a == 1){
            return 0;
        }
        if (a == -1){
            return 180;
        }
        if (a < 1 && a > -1)
        {
            do
            {
                if (Math.cos(b * Math.PI / 180) >= a)
                {
                    c0 = b;
                    b = (c0 + c1) / 2;
                }
                if (Math.cos(b * Math.PI / 180) <= a)
                {
                    c1 = b;
                    b = (c0 + c1) / 2;
                }
            }
            while (Math.abs(c0 - c1) > 0.00001);
        }
        return b;
    }
    public static void main(String[] args) {
//        String aaa = "[{\"lng\":119.11585,\"lat\":36.72355},{\"lng\":119.11576,\"lat\":36.71874},{\"lng\":119.1422,\"lat\":36.71963},{\"lng\":119.14143,\"lat\":36.72741},{\"lng\":119.14143,\"lat\":36.72741}]";
//        JSONArray array = JSONArray.parseArray(aaa);
//        String lnglat = "";
//        for (int i = 0; i < array.size(); i++) {
//            JSONObject json = JSON.parseObject(array.get(i).toString());
//            lnglat += i > 0 ? ";" : "";
//            lnglat += json.getString("lng") + "," + json.getString("lat");
//        }
//        log.info(lnglat);
//
//        boolean a = isPtInPoly(119.12941, 36.7217, lnglat);
//        log.info(a);
//
//        double s = getDistance(119.11585, 36.72354, lnglat);
//        log.info(s);
//
//        Long aaaa = measureDistance(119.12941, 36.7217, 119.12941, 36.7216);
//        log.info(aaaa);
//        boolean inside = false;
//        Double lon = 119.09949;
//        Double lat = 36.73615;
//        String bb = "[{\"lng\":119.10041,\"lat\":36.73611},{\"lng\":119.10118,\"lat\":36.73607},{\"lng\":119.10123,\"lat\":36.73647},{\"lng\":119.09908,\"lat\":36.73643}]";
//        JSONArray array = JSONArray.parseArray(bb);
//        if (array.size() > 0) {
//            String area = "";
//            for (int j = 0; j < array.size(); j++) {
//                JSONObject json = JSON.parseObject(array.get(j).toString());
//                area += j > 0 ? ";" : "";
//                area += json.getString("lng") + "," + json.getString("lat");
//            }
//            inside = DistanceUtils.getDistance(lon, lat, area) < 464;
//        }
//        log.info(inside);
//
//        log.info(insideLine(lon,lat,bb));
    }
}
